using System;
using System.Collections.Generic;
using System.Text;
using Cysharp.Threading.Tasks;
using Framework.Helper;
using Framework.StateMechine;
using Game.Hotfix;
using UnityEngine;
using UnityEngine.Networking;

namespace Game.Hotfix
{
    public class HotfixLoadChecksum : StateBase
    {
        private Game.Hotfix.Hotfix hotfix;

        public override async UniTask OnEnter(StateArgs _args)
        {
            hotfix = stateMachine.owner as Game.Hotfix.Hotfix;
            Debug.Log($"hotfix load checksum, hotfix url: {hotfix.hotfixServerDto.url}");
            await base.OnEnter(_args);
            
            // 第一种
            // await LoadLocalChecksum();
            // await LoadRemoteChecksum();
            
            // 第二种
            await UniTask.WhenAll(LoadLocalChecksum(), LoadRemoteChecksum());
            
            stateMachine.Change(HotfixState.VerifyChecksum);
        }

        private async UniTask LoadLocalChecksum()
        {
            await UniTask.CompletedTask;

            AssetBundle assetBundle = null;
            try
            {
                // assetBundle = AssetBundleHelper.LoadBundleSync(HotfixConst.localChecksumFile);
                assetBundle = await AssetBundleHelper.LoadAssetBundleAsync(HotfixConst.localChecksumFile, false);
            }
            catch (Exception e)
            {
                Debug.Log("cannot load local checksum. error: " + e.Message);
            }
            if (assetBundle == null)
                return;
            
            var asset = assetBundle.LoadAsset<ResourceChecksumData>("checksum.asset");
            for(int i = 0;i < asset.ChecksumList.Count; i++)
            {
                hotfix.localChecksum[asset.ChecksumList[i].filename] = asset.ChecksumList[i];
            }
            
            assetBundle.Unload(false);
        }

        private async UniTask LoadRemoteChecksum()
        {
            string remoteURL = $"{hotfix.hotfixServerDto.url}?version={hotfix.hotfixServerDto.version}&res={HotfixConst.remoteChecksumFile}";
            Debug.Log("[HotfixLoadChecksum] requestRemoteChecksum  remoteURL: " + remoteURL);

            DownloadHandler downloadHandler = null;
            try
            {
                UnityWebRequest remoteReq = new UnityWebRequest(remoteURL, UnityWebRequest.kHttpVerbGET, new DownloadHandlerBuffer(), null);
                remoteReq.timeout = 5;
                await remoteReq.SendWebRequest();
                
                downloadHandler = remoteReq.downloadHandler;
            }
            catch (Exception e)
            {
                Debug.Log("[HotfixLoadChecksum] get remote checksum error, error: " + e.Message);
            }
            if (downloadHandler == null)
            {
                stateMachine.Change(HotfixState.Result, new HotfixArgs()
                {
                    arg = "下载远程checksum文件失败",
                    errorCode = HotfixDownloadErrorCode.ErrorLoadRemoteChecksumFail,
                });
                return;
            }

            byte[] data = downloadHandler.data;
            Debug.Log("AAAA  " + data.Length);
            // 因打ab时, ab资源头部添加 1byte, 故从远程资源服务器下载后头部第二位读取
            AssetBundleHelper.ConvertAssetBundleBytes(data, out byte[] resBytes); // checksum.asset.ab  2918
            Debug.Log("BBBB  " + resBytes.Length);

            hotfix.remoteChecksumData = resBytes;

            AssetBundle assetBundle = AssetBundle.LoadFromMemory(resBytes);
            var asset = assetBundle.LoadAsset<ResourceChecksumData>("checksum.asset");
            
            for (int i = 0; i < asset.ChecksumList.Count; i++)
            {
                hotfix.remoteChecksum[asset.ChecksumList[i].filename] = asset.ChecksumList[i];
            }

            foreach (KeyValuePair<string,ChecksumData> remote in hotfix.remoteChecksum)
            {
                // Debug.Log("======  " + remote.Key + "  " + remote.Value.filesize);
            }
        
            assetBundle.Unload(false);
        }
    }
}

